package com.smarthome.api.mobile.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.alibaba.druid.util.StringUtils;
import com.smarthome.common.mobile.Service;
import com.smarthome.core.account.AccountDoorService;
import com.smarthome.core.housemanager.ResidenceFeeService;
import com.smarthome.core.payment.alipay.AlipayService;
import com.smarthome.core.propertymanager.PropertyFeePaymentService;
import com.smarthome.core.propertymanager.PropertyMoneyService;
import com.smarthome.domain.bean.ShAccountDoor;
import com.smarthome.domain.bean.ShPropertyFee;
import com.smarthome.domain.bean.ShPropertyFeePayment;
import com.smarthome.domain.bean.ShResidenceFee;
import com.smarthome.domain.enums.AccountDoorStatus;
import com.smarthome.domain.enums.AppIdEnum;
import com.smarthome.domain.enums.PropertyFeePaymentStatusEnum;
import com.smarthome.domain.enums.PropertyFeeStatusEnum;
import com.smarthome.domain.mobile.MobileCodeEnum;
import com.smarthome.domain.mobile.MobileResponse;
import com.smarthome.domain.mobile.req.MobileAccountPropertyFeeReuqest;

@org.springframework.stereotype.Service("mobile.account.propertyfee")
public class MobilePropertyFeeService implements Service<MobileResponse<Map<String, String>>> {

    @Resource
    private AccountDoorService accountDoorService;
    @Resource
    private PropertyMoneyService propertyMoneyService;
    @Resource
    private PropertyFeePaymentService propertyFeePaymentService;
    @Resource
    private AlipayService alipayService;
    @Resource
    private ResidenceFeeService residenceFeeService;

    /**
     * 获取用户已认证的所有的门牌
     * @param request
     * @param response
     */
    public void getAccountDoor(MobileAccountPropertyFeeReuqest request, MobileResponse<List<ShAccountDoor>> response) {
        ShAccountDoor accountDoor = new ShAccountDoor();
        accountDoor.setAccountId(request.getAccountId());
        accountDoor.setStatus(AccountDoorStatus.OK.getType());// 审核通过的房屋
        // accountDoor.setResidenceId(request.getAccount().getResidenceId());//当前小区
        List<ShAccountDoor> accountDoors = accountDoorService.queryDataListByCondition(accountDoor);
        for (ShAccountDoor door : accountDoors) {
            ShResidenceFee fee = residenceFeeService.residenceFeeByResidenceId(door.getResidenceId());
            if (null == fee || null == fee.getBaseFee() || null == fee.getOtherFee()) {
                continue;
            }
            door.setBaseFee(fee.getBaseFee());
            door.setOtherFee(fee.getOtherFee());
            // 计算公式
            String formula = fee.getBaseFee() / 100 + "元/平方*" + door.getSpace() + "+" + fee.getOtherFee() / 100;
            door.setFormula(formula);
        }
        response.setData(accountDoors);
    }

    /**
     * 获取房屋管理界面的所有房屋(认证和未认证的)
     * @param request
     * @param response
     */
    public void getManageDoors(MobileAccountPropertyFeeReuqest request, MobileResponse<List<Map<String, Object>>> response) {
        ShAccountDoor accountDoor = new ShAccountDoor();
        accountDoor.setAccountId(request.getAccountId());
        List<ShAccountDoor> accountDoors = accountDoorService.queryDataListByCondition(accountDoor);
        response.setData(groupAccountDoorData(accountDoors));
    }

    /**
     * 获取门牌下指定月份的物业费
     * @param request
     * @param response
     */
    public void getFeeByDoorId(MobileAccountPropertyFeeReuqest request, MobileResponse<List<ShPropertyFee>> response) {
        ShPropertyFee fee = new ShPropertyFee();
        if (null == request.getDoorId() || StringUtils.isEmpty(request.getMonth())) {
            response.setMobileCodeObj(MobileCodeEnum.ACCOUNT_NOT_FULL);
        } else {
            fee.setDoorId(request.getDoorId());
            fee.setMonth(formatChineseTime(request.getMonth()));

            // 获取选择月份物业费
            List<ShPropertyFee> fees = propertyMoneyService.getByDoorIdAndMonth(fee);
            response.setData(fees);
        }

    }

    /**
     * 获取门牌下缴费近期记录
     * @param request
     * @param response
     */
    public void getFeeRecord(MobileAccountPropertyFeeReuqest request, MobileResponse<List<ShPropertyFee>> response) {

        ShPropertyFee feePay = new ShPropertyFee();
        feePay.setDoorId(request.getDoorId());
        feePay.setStatus(1);
        feePay.setOrderField("month");
        feePay.setOrderFieldType("desc");
        feePay.setStartIndex(0);
        feePay.setEndIndex(3);

        List<ShPropertyFee> record = propertyMoneyService.getByDoorIdAndBetweenMonth(feePay);

        response.setData(record);
    }

    /**
     * 获取月份区间的未交物业费
     * @param request
     * @param response
     */
    public void getFeeByDoorAndMonthZone(MobileAccountPropertyFeeReuqest request, MobileResponse<Map<String, Object>> response) {
        ShPropertyFee fee = new ShPropertyFee();
        fee.setDoorId(request.getDoorId());
        fee.setBeginMonth(formatChineseTime(request.getStartMonth()));
        fee.setEndMonth(formatChineseTime(request.getEndMonth()));
        fee.setStatus(2);// 未交物业费
        List<ShPropertyFee> fees = propertyMoneyService.getByDoorIdAndBetweenMonth(fee);

        Map<String, Object> resMap = new HashMap<String, Object>();
        long count = 0L;
        StringBuilder feeIds = new StringBuilder();
        for (int i = 0; i < fees.size(); i++) {
            ShPropertyFee nowfee = fees.get(i);
            count += nowfee.getAmount();
            feeIds.append(i == fees.size() - 1 ? nowfee.getId() + "" : nowfee.getId() + "#");
        }
        resMap.put("amount", count);
        resMap.put("feeIds", feeIds.toString());
        response.setData(resMap);
    }

    /**
     * 生成缴费记录
     * @param request
     * @param response
     */
    public void applyPay(MobileAccountPropertyFeeReuqest request, MobileResponse<Map<String, String>> response) {
        String[] feeIds = request.getFeeIds().split("#");
        long totalAmount = 0L;
        for (String feeId : feeIds) {
            Long fid = Long.parseLong(feeId);
            ShPropertyFee fee = propertyMoneyService.getFeeById(fid);
            if (null == fee || fee.getStatus() == PropertyFeeStatusEnum.PAY_YES.getCode()) {
                response.setMobileCodeObj(MobileCodeEnum.PROPERTY_FEE_NOT_FOUND);
                return;
            }
            totalAmount += fee.getAmount();
        }
        // 生成物业缴费记录
        ShPropertyFeePayment payment = new ShPropertyFeePayment();
        payment.setAccountId(request.getAccountId());
        payment.setChannelSn(request.getChannelSn());
        payment.setFeeIds(request.getFeeIds());
        payment.setAmount(totalAmount);
        payment.setStatus(PropertyFeePaymentStatusEnum.DEPEND.getCode());
        long paymentSn = new Date().getTime();
        payment.setPaymentSn(AppIdEnum.PROPERTY.getCode() + "_" + String.valueOf(paymentSn));
        propertyFeePaymentService.saveOrEdit(payment);
        Map<String, String> res = new HashMap<String, String>();
        res.put("alipayStr", alipayService.payByAlipayMobile(AppIdEnum.PROPERTY.getCode(), payment.getPaymentSn(), totalAmount, "物业费"));
        response.setData(res);
    }

    /**
     * 缴费成功生成记录
     * @param request
     * @param response
     */
    public void payFeeByDoorId(MobileAccountPropertyFeeReuqest request, MobileResponse<?> response) {
        String[] feeIds = request.getFeeIds().split("#");
        for (String feeId : feeIds) {
            // Long fid = Long.parseLong(feeId);
            // ShPropertyFee fee = propertyMoneyService.getFeeById(fid);
            // // 更改物业费状态
            // propertyMoneyService.updateStatusById(fid);
            //
            // // 生成物业缴费记录
            // ShPropertyFeePayment payment = new ShPropertyFeePayment();
            // payment.setAccountId(request.getAccountId());
            // payment.setChannelSn(request.getChannelSn());
            // payment.setFeeId(request.getFeeIds());
            // payment.setAmount(fee.getAmount());
            // propertyFeePaymentService.saveOrEdit(payment);
        }
    }

    private String formatChineseTime(String month) {
        SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMM");
        try {
            Date source = timeFormat.parse(month);
            timeFormat.applyPattern("yyyy年MM月");
            return timeFormat.format(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return month;
    }

    private void setDefaultMonth(ShPropertyFee feePay) {
        Date now = new Date(); // 当前时间
        Date before = new Date();
        Calendar calendar = Calendar.getInstance(); // 得到日历
        calendar.setTime(now);// 把当前时间赋给日历
        calendar.add(calendar.MONTH, -8); // 设置为前3月
        before = calendar.getTime(); // 得到前3月的时间

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM"); // 设置时间格式
        String defaultStartDate = sdf.format(before); // 格式化前3月的时间
        String defaultEndDate = sdf.format(now); // 格式化当前时间

        feePay.setBeginMonth(formatChineseTime(defaultStartDate));
        feePay.setEndMonth(formatChineseTime(defaultEndDate));
    }

    /**
     * 分组展示数据
     * @param data
     * @return
     */
    private List<Map<String, Object>> groupAccountDoorData(List<ShAccountDoor> data) {
        Map<String, List<ShAccountDoor>> resData = new HashMap<String, List<ShAccountDoor>>();

        // 获取分组数据
        for (ShAccountDoor accountDoor : data) {
            List<ShAccountDoor> res = resData.get(accountDoor.getResidenceName());
            if (null == res || res.size() <= 0) {
                res = new ArrayList<ShAccountDoor>();
                res.add(accountDoor);
            } else {
                res.add(accountDoor);
            }
            resData.put(accountDoor.getResidenceName(), res);
        }

        // 组装数据格式
        List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();
        for (String key : resData.keySet()) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("residenceName", key);
            map.put("doors", resData.get(key));
            datas.add(map);
        }

        return datas;
    }
}
